package com.seguriapp.paperworks.gwt.server;

import static com.google.common.collect.Lists.newArrayList;

import java.util.List;

import net.customware.gwt.dispatch.server.ExecutionContext;
import net.customware.gwt.dispatch.shared.DispatchException;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.log4j.Logger;
import org.restlet.data.MediaType;
import org.restlet.resource.ClientResource;

import com.seguriapp.common.config.GlobalConfigLoader;
import com.seguriapp.common.gwt.server.AbstractSeguriAppHandler;
import com.seguriapp.entities.Paperwork;
import com.seguriapp.entities.PaperworkAttribute;
import com.seguriapp.entities.PaperworkAttributeCode;
import com.seguriapp.paperworks.gwt.shared.GetPaperworksListAction;
import com.seguriapp.paperworks.gwt.shared.GetPaperworksListResult;

public class GetPaperworksListHandler extends AbstractSeguriAppHandler<GetPaperworksListAction, GetPaperworksListResult> {

  private static final Logger LOGGER = Logger.getLogger(GetPaperworksListHandler.class);

  public Class<GetPaperworksListAction> getActionType() {
    return GetPaperworksListAction.class;
  }

  public GetPaperworksListResult execute(GetPaperworksListAction action, ExecutionContext context) throws DispatchException {

    final GetPaperworksListResult result = new GetPaperworksListResult();
    try {
      final String serverUrl = GlobalConfigLoader.getInstance().getGlobalConfig().getBackEndUrl();
      final String url = serverUrl.concat(GlobalConfigLoader.getInstance().getGlobalConfig().getListPaperworks());
      final ClientResource resource = new ClientResource(url);
      final String paperworksListJs = resource.get(MediaType.TEXT_PLAIN).getText();
      LOGGER.info("Data received : \n" + paperworksListJs);
      result.setPaperworksList(getJsonDataFromString(paperworksListJs));
    } catch (Exception e) {
      LOGGER.error("Error obtaining the initial data \n", e);
    }
    return result;
  }

  private List<Paperwork> getJsonDataFromString(final String paperworksListJs) {
    final List<Paperwork> paperworksList = newArrayList();
    final JSONObject root = JSONObject.fromObject(paperworksListJs);
    JSONArray dataArray = null;
    JSONObject jo = null;
    if (root.has("paperworks")) {
      dataArray = root.getJSONArray("paperworks");
      if (dataArray != null) {
        for (int i = 0; i < dataArray.size(); i++) {
          jo = dataArray.getJSONObject(i);
          final Paperwork paperwork = processjSONObject(jo);
          if (paperwork != null) {
            paperworksList.add(paperwork);
          }
        }
      }
    }
    return paperworksList;
  }

  private Paperwork processjSONObject(final JSONObject jo) {
    if (jo.has("id") && jo.has("name")) {
      final Paperwork paperwork = new Paperwork();
      paperwork.setId(jo.getLong("id"));
      paperwork.setName(jo.getString("name"));
      paperwork.setCost(jo.has("cost") ? jo.getString("cost") : null);
      paperwork.setDuration(jo.has("duration") ? jo.getString("duration") : null);
      paperwork.setHasFile(jo.has("hasFile") ? jo.getBoolean("hasFile") : null);
      if (jo.has("attributeList")) {
        final List<PaperworkAttribute> paperworkAttributeList = newArrayList();
        JSONArray dataArray = null;
        JSONObject jo2 = null;
        dataArray = jo.getJSONArray("attributeList");
        if (dataArray != null) {
          for (int i = 0; i < dataArray.size(); i++) {
            jo2 = dataArray.getJSONObject(i);
            final PaperworkAttribute paperworkAttribute = processjSONObject2(jo2);
            if (paperworkAttribute != null) {
              paperworkAttributeList.add(paperworkAttribute);
            }
          }
        }
        paperwork.setAttributeList(paperworkAttributeList);
      }
      return paperwork;
    }
    return null;
  }

  private PaperworkAttribute processjSONObject2(final JSONObject jo) {
    if (jo.has("id") && jo.has("value") && jo.has("code")) {
      final PaperworkAttribute paperworkAttribute = new PaperworkAttribute();
      paperworkAttribute.setId(jo.getLong("id"));
      paperworkAttribute.setValue(jo.getString("value"));
      paperworkAttribute.setCode(PaperworkAttributeCode.getEnumByString(jo.getString("code")));
      return paperworkAttribute;
    }
    return null;
  }

}
